// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import { User } from "@/entities/User";
import { initORM } from "@/utils";
import type { NextApiRequest, NextApiResponse } from "next";
import crypto from "crypto";
// import { MetadataStorage } from "@mikro-orm/core";
// import jwt from "jsonwebtoken";
import * as jose from "jose";
import { pickData, createMd5 } from "@/utils/back";

type Data = {
  name: string;
  [key: string]: any;
};

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse<APIRes>
) {
  if (req.method !== "POST") {
    res.status(405).json({
      success: false,
      data: {},
      message: "Method not allowed",
    });
    return;
  }
  const { email, password } = req.body ?? {};
  if (!email || !password) {
    res.status(400).json({
      success: false,
      data: {},
      message: "Bad request, missing email or password",
    });
    return;
  }

  const em = await initORM();
  const user = await em.findOne(User, { email });

  const setTokenCookie = async (userId: number) => {
    const expiredDate = new Date(Date.now() + 1000 * 60 * 60 * 24 * 3);
    const joJWT = new jose.SignJWT({ userId });
    const token = await joJWT
      .setProtectedHeader({ alg: "HS256", typ: "JWT" })
      .setExpirationTime("3 days")
      .sign(new TextEncoder().encode(process.env.JWT_SECRET!));

    res.setHeader(
      "Set-Cookie",
      // @ts-ignore
      `token=${token}; Expires=${expiredDate?.toGMTString()}; Path=/; HttpOnly`
    );
  };

  if (user) {
    // user login

    const correctPass = user.pass;
    const inputPass = createMd5(password);
    if (correctPass !== inputPass) {
      res.status(400).json({
        success: false,
        message: "Bad request, invalid password",
        data: {},
      });
      return;
    }

    if (user.disabled) {
      res.status(401).json({
        success: false,
        message: "Bad authentication, user disabled",
        data: {},
      });
      return;
    }

    await setTokenCookie(user.id);

    res.status(200).json({
      success: true,
      // data: pickData(user, ["name", "email", "avatar"]),
      data: user,
      message: "Log in success",
    });
  } else {
    // user register
    const pass = createMd5(password);
    const firstName = email.replace(/@.+$/, "").replace(/\..+$/, "");
    const name = firstName.charAt(0).toUpperCase() + firstName.slice(1);
    const newUser = await em.create(User, {
      email,
      pass,
      name,
      role: 2,
      disabled: 0,
    });
    await em.persistAndFlush(newUser);

    const user = await em.findOne(User, { email });
    if (!user) {
      res.status(400).json({
        success: false,
        message: "Bad request, user not found",
        data: {},
      });
    } else {
      await setTokenCookie(user.id);
      res.status(200).json({
        success: true,
        message: "Register success ",
        // data: pickData(user, ["name", "email", "avatar"]),
        data: user,
      });
    }
  }
}
